class ChannelEncoding:
    def __init__(self,inputList):
        self.NewList(inputList)
    def NewList(self,inputList):
        if len(inputList)%4!=0:
            raise Exception("长度必须为4的倍数!")
        self.inputList = inputList
        self.Humming()
        self.circleMake()
        self.Convolution()
    def Decoder(self,**kwargs):
        if 'humming' in kwargs:
            self.humming=kwargs['humming']
            self.HanmmingCheck()
            return
        if 'circleList' in kwargs:
            self.circleList=kwargs['circleList']
            self.circleCheck()
            return
        # if 'convlution' in kwargs:
        #     self.convolution=kwargs['convlution']
        #     return
    def circleMake(self): #x^3+x+1
        n = int(len(self.inputList) / 4)
        circleList =[]
        for emu in range(0,n):
            registor = [0, 0, 0]
            inputList = [0, 0, 0]
            inputList.extend(self.inputList[emu*4:(emu+1)*4])
            for i in range(len(inputList)-1,-1,-1):
                temp = registor[2]
                registor[2] = registor[1]
                registor[1] = (registor[0]+temp)%2
                registor[0] = (temp+inputList[i])
            tempList=self.inputList[emu*4:(emu+1)*4].copy()
            tempList.extend(registor)
            circleList.extend(tempList)
        self.circleList=circleList


    def circleCheck(self):

        n = int(len(self.circleList) / 7)
        circleList=self.circleList.copy()
        for emu in range(0,n):
            registor = [0, 0, 0]
            for i in range(0,7):
                temp = registor[2]
                registor[2] = (registor[1]+temp)%2
                registor[1] = registor[0]
                registor[0] = (circleList[emu*7:(emu+1)*7][i]+temp)%2
            for i in range(0,3):
                if registor[i] != 0:
                    print("wrong")
                    return 0
        print("Circle Check Result is all right")

    def Convolution(self):
        n = int(len(self.inputList)/3)
        convolution = [0] * (n*4)
        count = [0,0]
        for i in range(0,n):
            convolution[4*i] = self.inputList[3*i]
            convolution[4*i+1] = self.inputList[3*i+1]
            convolution[4*i+2] = self.inputList[3*i+2]
            convolution[4*i+3] = (self.inputList[3*i]+self.inputList[3*i+1]+self.inputList[3*i+2]+count[1])%2
            count[1] = (self.inputList[3*i]+self.inputList[3*i+2]+count[0])%2
            count[0] = (self.inputList[3*i]+self.inputList[3*i+1])%2
        self.convolution=convolution

    def Humming(self):
        n = int(len(self.inputList)/4)
        humming = [0] * (n*7)
        for i in range(0,n):
            humming[7*i] = self.inputList[4*i]
            humming[7*i+1] = self.inputList[4*i+1]
            humming[7*i+2] = self.inputList[4*i+2]
            humming[7*i+3] = self.inputList[4*i+3]
            humming[7*i+4] = (self.inputList[4*i+1]+self.inputList[4*i+2]+self.inputList[4*i+3])%2
            humming[7*i+5] = (self.inputList[4*i]+self.inputList[4*i+2]+self.inputList[4*i+3])%2
            humming[7*i+6] = (self.inputList[4*i]+self.inputList[4*i+1]+self.inputList[4*i+3])%2
        self.humming=humming

    def HanmmingCheck(self):
        n = int(len(self.humming)/7)
        registor = [0,0,0]
        origin =[]
        flag = 0
        for i in range(0,n):
            registor[2] = (self.humming[i*7+1]+self.humming[i*7+2]+self.humming[i*7+3]+self.humming[i*7+4])%2
            registor[1] = (self.humming[i*7]+self.humming[i*7+2]+self.humming[i*7+3]+self.humming[i*7+5])%2
            registor[0] = (self.humming[i*7]+self.humming[i*7+1]+self.humming[i*7+3]+self.humming[i*7+6])%2
            for j in range(0,len(registor)):
                if registor[j] != 0:
                    print("wrong")
                    return
            if flag == 0:
                part = self.humming[i*7:i*7+4]
                if i == 0:
                    origin = part
                else:
                    origin.extend(part)
        print("hanming_check:",origin)
        return origin

    # ChannelCoding.HanmmingCheck(out_han)